<template>
  <component
    :is="column.search?.render ?? `el-${column.search?.el}`"
    v-bind="{ ...handleSearchProps, ...placeholder, searchParam: _searchParam, clearable }"
    v-model.trim="_searchParam[column.search?.key ?? handleProp(column.prop!)]"
    :data="column.search?.el === 'tree-select' ? columnEnum : []"
    :options="['cascader', 'select-v2'].includes(column.search?.el!) ? columnEnum : []"
    @change="changeMethod(column)"
    @input="inputMethod(column)"
  >
    <template v-if="column.search?.el === 'cascader'" #default="{ data }">
      <span>{{ data[fieldNames.label] }}</span>
    </template>
    <template v-if="column.search?.el === 'select'">
      <component
        :is="`el-option`"
        v-for="(col, index) in columnEnum"
        :key="index"
        :label="_transitionLanguages('table', col[fieldNames.label])"
        :value="col[fieldNames.value]"
      ></component>
    </template>
    <slot v-else></slot>
  </component>
</template>

<script setup lang="ts" name="SearchFormItem">
import { computed, inject, ref } from 'vue';
import { handleProp } from '@/utils';
import { ColumnProps } from '@/components/ProTable/interface';
import { useI18n } from 'vue-i18n';

// 语言转换
const _transitionLanguages = (v: string, l: string): string => {
  return transitionLanguages(v, l);
};

const i18n = useI18n();

interface SearchFormItem {
  column: ColumnProps;
  searchParam: { [key: string]: any };
}
const props = defineProps<SearchFormItem>();
// Re receive SearchParam
const _searchParam = computed(() => props.searchParam);

// 判断 fieldNames 设置 label && value && children 的 key 值
const fieldNames = computed(() => {
  return {
    label: props.column.fieldNames?.label ?? 'label',
    value: props.column.fieldNames?.value ?? 'value',
    children: props.column.fieldNames?.children ?? 'children'
  };
});

const changeMethod = (column: ColumnProps) => column.search?.changeMethod && column.search.changeMethod(props.searchParam);
const inputMethod = (column: ColumnProps) => column.search?.inputMethod && column.search.inputMethod(props.searchParam);

// 接收 enumMap (el 为 select-v2 需单独处理 enumData)
const enumMap = inject('enumMap', ref(new Map()));

const columnEnum = computed(() => {
  let enumData = enumMap.value.get(props.column.prop);

  if (!enumData) return [];

  if (props.column.search?.el === 'select-v2' && props.column.fieldNames) {
    enumData = enumData.map((item: { [key: string]: any }) => {
      return { ...item, label: item[fieldNames.value.label], value: item[fieldNames.value.value] };
    });
  }

  return enumData;
});

// 处理透传的 searchProps (el 为 tree-select、cascader 的时候需要给下默认 label && value && children)
const handleSearchProps = computed(() => {
  const label = fieldNames.value.label;
  const value = fieldNames.value.value;
  const children = fieldNames.value.children;
  const searchEl = props.column.search?.el;
  let searchProps: any = props.column.search?.props ?? {};

  if (searchEl === 'tree-select') {
    searchProps = { ...searchProps, props: { ...searchProps.props, label, children }, nodeKey: value };
  }
  if (searchEl === 'cascader') {
    searchProps = { ...searchProps, props: { ...searchProps.props, label, value, children } };
  }
  return searchProps;
});

// 处理默认 placeholder
const placeholder = computed(() => {
  const search = props.column.search;

  if (['datetimerange', 'daterange', 'monthrange'].includes(search?.props?.type || '')) {
    return { rangeSeparator: '至', startPlaceholder: '开始时间', endPlaceholder: '结束时间' };
  }

  const p = search?.props?.placeholder;

  let prefix = search?.el?.includes('input')
    ? transitionLanguages(`placeholder`, 'pleaseEnter')
    : transitionLanguages(`placeholder`, 'pleaseSelect');
  // 英文是需要添加空格分开单词
  prefix += i18n.locale.value === 'en' ? ' ' : '';

  const placeholder = p
    ? prefix + transitionLanguages(`placeholder`, p)
    : prefix + transitionLanguages(`table`, props.column.search?.label || props.column.label || '');

  return { placeholder };
});

// 是否有清除按钮 (当搜索项有默认值时，清除按钮不显示)
const clearable = computed(() => {
  const search = props.column.search;
  // return search?.props?.clearable ?? (search?.defaultValue == null || search?.defaultValue == undefined);
  return search?.props?.clearable ?? true;
});
</script>
